Merged
Conversation
Implement map type rendering plus lowering/lifting/deallocation support across the C, C++, C#, Go, MoonBit, and Markdown backends, and add map codegen/runtime tests. This aligns non-Rust generators with core map ABI support and fixes the Go test harness module replacement path needed for map codegen verification. Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
d9c32e0 to
0a302d8
Compare
Defer map codegen for MoonBit, Go, C#, C++, and C to future PRs that include runtime tests and review from language-specific maintainers. Only todo!() stubs for the new MapLower/MapLift/ IterMapKey/IterMapValue/GuestDeallocateMap instruction variants are kept so exhaustive matches compile.
This change was a fix for a latent bug from the vanity imports migration but is unrelated to map support. Removing to keep the PR focused on Rust.
- Make `InterfaceGenerator::type_map` a required trait method instead of
providing a default `todo!()` impl, so missing implementations are
caught at compile time rather than runtime.
- Remove `RuntimeItem::MapType` indirection in the Rust backend; reference
`{rt}::Map` directly instead of emitting a `pub use` re-export.
- Fix borrowed map rendering to use `&Map<K, V>` instead of the
incorrect `&[(K, V)]` slice syntax that was copy-pasted from lists.
- Add explanatory comments on map ABI methods that reuse list
read/write helpers (maps share the list<tuple<K, V>> memory layout).
- Add explicit `type_map` todo stubs to C, C++, C#, Go, and MoonBit
backends.
- Make `anonymous_type_map` a required method on `AnonymousTypeGenerator` trait (no default impl), consistent with all other methods in the trait. - Add explicit `anonymous_type_map` todo!() implementation to C backend. - Fix map runner test to construct proper Map types instead of passing slice literals, matching the generated `&Map<K, V>` parameter signatures.
The map.wit codegen test hits todo!() panics in backends that don't yet implement map support (C, C++, C#, Go, MoonBit). Add map.wit to each backend's should_fail_verify so CI treats these as expected failures.
- Run cargo fmt to fix formatting in c/lib.rs, test/c.rs, test/moonbit.rs.
- Use starts_with("map.wit") for the C backend's should_fail_verify to
catch all codegen test variants (no-sig-flattening, autodrop, async).
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Add runtime tests for empty maps, option values, maps inside records, inline anonymous map types, and a 100-entry stress test. Expand codegen tests with option values, nested maps, record values, bool keys, and char keys.
Exercise additional ABI code paths: nested map<K, map<K2, V>> with recursive lower/lift blocks, multiple map parameters with independent ptr/len pairs, map as a variant arm payload, map inside result<ok, err>, and tuple-with-map in codegen.
Exercise map inside an anonymous tuple (filter_mode_preserve_top path) and the single-entry boundary case.
alexcrichton
reviewed
Apr 7, 2026
Member
alexcrichton
left a comment
There was a problem hiding this comment.
Ok thinking a bit more about this and the Rust side of things. Ultimately I feel that neither HashMap nor BTreeMap are the right types to use here. Given that I'm thinking that this needs to be more configurable in Rust to select the desired type, with some semi-reasonable default. What I'm thinking is something like this:
- Bindgen accepts a new
map_type: Foo-style option. Basically this makes it customizable as to what type exactly is used and enables users to specify their own types. For example if users wanted to doVec<(K, V)>that would be possible. - There's a trait in
wit-bindgen-the-crate called something liketrait WitMap. This would have methods for creation (pushing items into it) and iteration. These methods would be delegated to in the generated code (e.g. viaWitMap::push(&mut map, key, value). This provides a clear interface between generated code and the needs of the type that a map has. - Probably the default map is a
BTreeMapfor now. I don't think it's a slam dunk overHashMapbut neither is the other way around either. With this support it should be relatively easily interchangeable.
Instead of hardcoding HashMap/BTreeMap, introduce a WitMap trait that generated code delegates to for map construction, insertion, and length. This lets users swap in their own map type via the new `map_type` bindgen option. The default is BTreeMap (always, regardless of std).
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
- Unit tests for WitMap trait impls (BTreeMap, HashMap, reference blanket) - Proc-macro integration tests exercising map_type with HashMap and default - Codegen test variant running all .wit files with --map-type=HashMap
Remove `type Iter` and `wit_map_into_iter` from the `WitMap` trait and drop the `IntoIterator` bound from the blanket `&T` impl. This allows the blanket impl to apply at any reference depth (e.g. `&&BTreeMap`) which is needed when codegen emits `WitMap::wit_map_len(&map)` on an already-borrowed map. Generated lowering code now uses `IntoIterator::into_iter(map)` for iteration, which the standard library already provides for both owned and borrowed map types.
Use method syntax (.wit_map_len() and .into_iter()) in generated MapLower code instead of UFCS. This lets Rust's auto-deref handle &&BTreeMap operands that arise when the borrow-mode param wrapper adds an extra & prefix to already-borrowed map arguments. A scoped `use WitMap;` import is emitted so method resolution finds the trait's wit_map_len method.
Revert MapLower to use method syntax for length and iteration, matching the original pre-WitMap code. Method syntax auto-derefs through &&Map operands that arise in borrowed ownership modes. Simplify WitMap trait to just new/push (used only in MapLift). The map type must also provide .len() and implement IntoIterator, which all standard map types already do.
alexcrichton
reviewed
Apr 8, 2026
Member
alexcrichton
left a comment
There was a problem hiding this comment.
Thanks! Only one more minor thing and otherwise this looks good to me
Instead of calling .len() directly (which bypasses the WitMap trait and would break custom map types), generated code now calls .wit_map_len() using method syntax. The WitMap trait is brought into scope via a module-level `use _rt::WitMap;` import, avoiding the scoping issues that arose from emitting `use` inside nested blocks.
alexcrichton
approved these changes
Apr 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
map<K, V>support inwit-bindgencore ABI and backend codegen paths (C, C++, C#, Go, MoonBit), plus Markdown type renderingtests/codegen/map.witandtests/runtime/map/*crates/test/src/go.rsso generated map bindings resolvego.bytecodealliance.org/pkg/wit/*correctlyTest plan
cargo fmtcargo clippy --workspace --all-targets -- -D warningscargo checkcargo check -p wit-bindgen-corecargo check -p wit-bindgen-ccargo check -p wit-bindgen-cppcargo check -p wit-bindgen-csharpcargo check -p wit-bindgen-gocargo check -p wit-bindgen-moonbitcargo check -p wit-bindgen-markdowncargo run test --artifacts target/artifacts --runner cargo --languages go --filter map.wit tests/codegen